package com.ysd.service.config;

import com.ysd.service.service.ClockService;
import lombok.Data;
import org.eclipse.paho.client.mqttv3.MqttConnectOptions;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.integration.annotation.IntegrationComponentScan;
import org.springframework.integration.annotation.ServiceActivator;
import org.springframework.integration.channel.DirectChannel;
import org.springframework.integration.core.MessageProducer;
import org.springframework.integration.mqtt.core.DefaultMqttPahoClientFactory;
import org.springframework.integration.mqtt.core.MqttPahoClientFactory;
import org.springframework.integration.mqtt.inbound.MqttPahoMessageDrivenChannelAdapter;
import org.springframework.integration.mqtt.outbound.MqttPahoMessageHandler;
import org.springframework.integration.mqtt.support.DefaultPahoMessageConverter;
import org.springframework.messaging.MessageChannel;
import org.springframework.messaging.MessageHandler;

/**
 * MQTT客户端的配置类
 */
@Configuration
@IntegrationComponentScan
@Data
public class MqttConfig {

    @Value("${spring.mqtt.url}")
    private String mqttUrl;

    @Value("${spring.mqtt.username}")
    private String mqttUsername;

    @Value("${spring.mqtt.password}")
    private String mqttPassword;

    @Value("${spring.mqtt.client-id}")
    private String mqttClientId;

    // 设备端topic（程序向设备发送消息的topic）
    @Value("${spring.mqtt.device-topic}")
    private String mqttDeviceTopic;

    // 程序端topic（程序接收设备消息的topic）
    @Value("${spring.mqtt.procedure-topic}")
    private String mqttProcedureTopic;

    @Autowired
    private ClockService clockService;


    /**
     * 配置 MQTT 客户端连接选项
     */
    @Bean
    public MqttPahoClientFactory mqttClientFactory() {
        DefaultMqttPahoClientFactory factory = new DefaultMqttPahoClientFactory();
        MqttConnectOptions options = new MqttConnectOptions();
        // 设置 MQTT Broker 地址 (可多条)
        options.setServerURIs(new String[]{mqttUrl});
        // 如果需要用户名和密码则设置：
         options.setUserName(mqttUsername);
         options.setPassword(mqttPassword.toCharArray());

        // 保持连接（可选）
        options.setKeepAliveInterval(60);
        options.setAutomaticReconnect(true);
        factory.setConnectionOptions(options);
        return factory;
    }

    /**
     * MQTT 入站通道（生产者）。这里订阅指定 topic(s)。
     * 你可以在构造方法中添加多个 topic，如 "topic1", "topic2"
     */
    @Bean
    public MessageProducer inbound() {
        // clientId 要保证唯一，否则多个客户端会互相挤掉连接
        String clientId = mqttClientId;
        // 指定需要订阅的topic，支持多个
        MqttPahoMessageDrivenChannelAdapter adapter =
                new MqttPahoMessageDrivenChannelAdapter(clientId,
                        mqttClientFactory(),
                        mqttProcedureTopic);
        // 超时时间
        adapter.setCompletionTimeout(5000);
        // 消息转换器
        adapter.setConverter(new DefaultPahoMessageConverter());
        // 设置 QoS， 0/1/2
        adapter.setQos(1);
        // 指定将消息发送到哪个 channel
        adapter.setOutputChannel(mqttInputChannel());
        return adapter;
    }

    /**
     * MQTT 入站通道（消息管道）。
     */
    @Bean
    public MessageChannel mqttInputChannel() {
        return new DirectChannel();
    }

    /**
     * 当订阅到消息后，通过此handler进行处理
     */
    @Bean
    @ServiceActivator(inputChannel = "mqttInputChannel")
    public MessageHandler handler() {
        return message -> {
            // message.getPayload() 就是 MQTT 消息内容
            String payload = message.getPayload().toString();
            System.out.println("收到 MQTT 消息 => " + payload);

            // 如果消息是 JSON，可用 Jackson 解析
            // 如果需要根据不同topic做不同处理，可从 message.getHeaders() 获取 topic
            // String topic = (String) message.getHeaders().get("mqtt_receivedTopic");

            // 调用clockService更新设备信息方法
            clockService.refreshDeviceData(payload, "在线");

        };
    }

    @Bean
    @ServiceActivator(inputChannel = "mqttOutboundChannel")
    public MessageHandler mqttOutbound() {
        MqttPahoMessageHandler messageHandler =
                new MqttPahoMessageHandler(mqttClientId, mqttClientFactory());
        messageHandler.setAsync(true);
        // 移除setDefaultTopic，因为通过MqttGateway发送消息时将指定主题
//        messageHandler.setDefaultTopic("some/otherTopic");
        return messageHandler;
    }

    @Bean
    public MessageChannel mqttOutboundChannel() {
        return new DirectChannel();
    }
}
